package com.yzh.board;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import pinboard.dataLayer.net.ActionCallback;
import pinboard.dataLayer.net.BaseClientPipe;
import pinboard.dataLayer.net.ClientPipeListener;
import pinboard.dataLayer.net.InstructClientPipe;
import pinboard.dataLayer.net.NetAddressInfo;
import pinboard.dataLayer.net.PipeContext;
import pinboard.dataLayer.net.RenderClientPipe;
import pinboard.dataLayer.potocol.Guid;
import pinboard.dataLayer.potocol.instructFormat.BaseResponse;
import pinboard.dataLayer.potocol.instructFormat.response.JoinMeetingResult;
import pinboard.dataLayer.potocol.instructFormat.response.LoginResponse;
import pinboard.dataLayer.potocol.instructFormat.response.UpdateMeetingStateResult;
import pinboard.dataLayer.potocol.op.InstructClientDecodeListener;
import pinboard.dataLayer.potocol.op.InstructClientDecoder;
import pinboard.dataLayer.potocol.op.InstructClientEncoder;
import pinboard.dataLayer.potocol.op.RenderClientDecodeListener;
import pinboard.dataLayer.potocol.op.RenderClientDecoder;
import pinboard.dataLayer.potocol.op.RenderClientEncoder;
import pinboard.dataLayer.potocol.renderFormat.AddRemoveStrokeParam;
import pinboard.dataLayer.potocol.renderFormat.InitResult;
import pinboard.dataLayer.potocol.renderFormat.RawHeadParam;
import pinboard.dataLayer.potocol.renderFormat.share.Stroke;

public class DataLayerActivity extends Activity {

    Button btnJoin;
    //QA
/*    String CST_APHost = "10.157.136.88";
    int CST_APPort = 6688;
    String CST_APLoginUserId = "test2";
    String CST_APLoginPwd = "test2";
    String CST_meetingRoom = "7563";*/

    //PROD
    String CST_APHost = "socket.pin.efoxconn.com";
    int CST_APPort = 6688;
    String CST_APLoginUserId = "f1027032";
    String CST_APLoginPwd = "123456";
    String CST_meetingRoom = "17040725";


    /*        address.setHost("116.6.66.233");
        address.setPort(443);
       address.setHost("socket.pin.efoxconn.com");
        address.setPort(6688);
        address.setHost("10.245.228.155");
        address.setPort(6000);

        address.setHost("10.202.86.72");
        address.setPort(6000);*/


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_data_layer);
        btnJoin = (Button) findViewById(R.id.join_btn);
        //Tester.test();

        btnJoin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (accessToken == null) {
                    processMsg("尚未登录服务器,无法加入会议", 1);
                    return;//没有登录成功
                }
                if (instructClientPipe != null && instructClientPipe.getState() == instructClientPipe.connectedState) {
                    byte[] data = InstructClientEncoder.joinMeeting(
                            instructClientPipe.getSequence(),
                            accessToken,
                            CST_APLoginUserId,
                            CST_meetingRoom,
                            "SDK演示用户",
                            "");
                    instructClientPipe.sendBytes(data);
                    processMsg("请求加入会议", 1);
                }
            }
        });

        ConnectDemo();
    }

    InstructClientPipe instructClientPipe = null;

    String accessToken = null;

    //region UI代码
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String txt = (String) msg.obj;
            if (msg.what == 0) {
                alert(txt);
            } else {
                toast(txt);
            }
        }
    };

    private void toast(String msg) {
        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
    }

    protected void alert(String msg) {
        new AlertDialog.Builder(this).setMessage(msg)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                    }
                }).show();
    }

    private void processMsg(String txt) {
        processMsg(txt, 0);
    }

    private void processMsg(String txt, int type) {
        Message msg = new Message();
        msg.obj = txt;
        msg.what = type;
        handler.sendMessage(msg);
    }
    //endregion

    private void ConnectDemo() {
        //STEP1 服务端地址设定
        NetAddressInfo address = new NetAddressInfo();
        address.setName("outServer");

        address.setHost(CST_APHost);
        address.setPort(CST_APPort);

        address.setAccount(CST_APLoginUserId);
        address.setPassword(CST_APLoginPwd);

   /*     address.setAccount("f1027032");
        address.setPassword("123456");*/
        address.setTag(null);

        //STEP2 连接管道事件监听-业务数据
        final InstructClientDecodeListener icdl = new InstructClientDecodeListener() {
            @Override
            public void onKeepAlive(BaseResponse response) {
                processMsg("msg onKeepAlive...", 1);
            }

            @Override
            public void onUpdateMeetingState(BaseResponse response, UpdateMeetingStateResult result) {
                processMsg("msg onUpdateMeetingState...", 1);
            }

            @Override
            public void onJoinMeeting(BaseResponse response, JoinMeetingResult result) {
                NetAddressInfo renderNAI = new NetAddressInfo();
                renderNAI.setName("render");
                renderNAI.setHost(result.shareUser.ip);
                renderNAI.setPort(result.shareUser.port);

                final RenderClientPipe rcp = new RenderClientPipe(renderNAI, new ClientPipeListener() {
                    @Override
                    public void onDisconnect(BaseClientPipe clientPipe) {
                        Object yyy = 123;
                    }

                    @Override
                    public void onMessage(BaseClientPipe clientPipe, byte[] data) {
                        RenderClientDecodeListener listener = new RenderClientDecodeListener() {
                            @Override
                            public void onInit(RawHeadParam head, InitResult result) {
                                super.onInit(head, result);
                            }
                        };
                        RenderClientDecoder.decode(data, listener);
                    }
                });

                rcp.connect(5000, new ActionCallback<PipeContext>() {
                    @Override
                    public void invoke(Object sender, PipeContext arg) {
                        if (arg.getNetState()) {
                            rcp.sendBytes(RenderClientEncoder.handShake(CST_APLoginUserId));
                        }
                    }
                });

                processMsg("msg onJoinMeeting...", 1);
            }
        };

        //STEP2 连接管道事件监听-掉线管理
        ClientPipeListener listener = new ClientPipeListener() {
            @Override
            public void onDisconnect(BaseClientPipe clientPipe) {
                //这里可以UI提示掉线
                accessToken = null;
                processMsg("断线...");
                clientPipe.connect(3000, new ActionCallback<PipeContext>() {
                    //连接完毕的回调
                    @Override
                    public void invoke(Object sender, PipeContext arg) {
                        boolean netState = arg.getNetState();//物理网络状态
                        if (!netState) {
                            if (arg.getRetryTimes() <= 20) {//最多重连20次
                                arg.setRetry(true);//继续重连
                                arg.setConnectTimeoutMillis(10000);//重连超时毫秒
                                arg.setWaitMillis(5000);//5000毫秒后重连
                                processMsg("断线,5秒后重连");
                            } else {
                                //这里可以UI提示重连失败
                                processMsg("断线重连超过最大次数");
                            }
                        } else {
                            LoginResponse response = (LoginResponse) arg.getResult();
                            if ("0".equals(response.errorCode)) {
                                //登录成功
                                processMsg("断线重连成功 " + response.result.displayName);
                            } else {
                                processMsg("断线重连登录失败 " + response.error);
                            }
                        }
                    }
                });
            }

            @Override
            public void onMessage(BaseClientPipe clientPipe, byte[] data) {
                InstructClientDecoder.decode(data, icdl);
            }
        };

        //STEP3 连接器回调监听
        final ActionCallback<PipeContext> connectCallback = new ActionCallback<PipeContext>() {
            //连接完毕的回调
            @Override
            public void invoke(Object sender, PipeContext arg) {
                accessToken = null;
                boolean netState = arg.getNetState();//物理网络状态
                if (!netState) {
                    if (arg.getRetryTimes() <= 10) {//最多重连10次
                        arg.setRetry(true);//继续重连
                        arg.setConnectTimeoutMillis(10000);//重连超时毫秒
                        arg.setWaitMillis(8000);//8000毫秒后重连
                        processMsg("连接失败，8秒后重连");
                    } else {
                        processMsg("重连超过最大次数");
                    }
                } else {
                    LoginResponse response = (LoginResponse) arg.getResult();
                    if ("0".equals(response.errorCode)) {
                        //登录成功
                        processMsg("连接已建立 " + response.result.displayName);
                        accessToken = response.result.accessToken;
                    } else {
                        processMsg("登录失败 " + response.error);
                    }
                }
            }
        };

        //STEP4 开线程启动连接
        instructClientPipe = new InstructClientPipe(address, listener);
        new Thread(new Runnable() {
            @Override
            public void run() {
                instructClientPipe.connect(3000, connectCallback);
            }
        }).start();
    }
}

